import json, pathlib
from openai import OpenAI
from docx import Document
import subprocess
import os
from typing import Dict, List


# 读取docx文件内容
def read_docx():
    file_path = r'D:\Programming_soft\ai_guard\requirements_doc\中信保需求.docx'
    """读取docx文件内容"""
    doc = Document(file_path)
    content = []

    # 读取段落
    for paragraph in doc.paragraphs:
        if paragraph.text.strip():  # 跳过空行
            content.append(paragraph.text)

    # 读取表格
    for table in doc.tables:
        for row in table.rows:
            row_content = []
            for cell in row.cells:
                row_content.append(cell.text.strip())
            content.append(" | ".join(row_content))

    return "\n".join(content)


# 代码分析
def code_analysis():
    file_path = pathlib.Path(__file__).parent.parent / 'semgrep_results.json'
    if file_path.exists():
        with open(file_path, 'r', encoding='utf-8') as f:
            json_data = json.load(f)
            prompt = f"""你是一个资深测试架构师。请根据以下静态代码分析结果，生成一份测试影响评估报告,只输出结果，不需要思考过程。

            代码变更概述：本次提交可能存在的问题如下

            分析数据（JSON）：
            {json_data}  

            请输出：
            1.  **核心变更点**：用一句话总结。
            2.  **直接受影响模块**：列出文件路径。
            3.  **间接可能受影响模块**：根据代码结构推测。
            4.  **测试建议**：指出需要重点测试的功能模块和测试类型（如：回归测试、集成测试、性能测试）。
            5.  **风险等级**：高/中/低，并说明理由。"""
            client = OpenAI(
                # 若没有配置环境变量，请用百炼API Key将下行替换为：api_key="sk-xxx",
                api_key='sk-8dcd9ec46bbe42f3947c71d27a21774d',
                base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
            )
            completion = client.chat.completions.create(
                # 模型列表：https://help.aliyun.com/zh/model-studio/getting-started/models
                model="qwen3-coder-flash",
                messages=[
                    {"role": "system", "content": "You are a helpful assistant."},
                    {"role": "user", "content": f"{prompt}"},
                ],
                # Qwen3模型通过enable_thinking参数控制思考过程（开源版默认True，商业版默认False）
                # 使用Qwen3开源版模型时，若未启用流式输出，请将下行取消注释，否则会报错
                # extra_body={"enable_thinking": False},
            )
            res = completion.model_dump()['choices'][0]['message']['content']
            return res
    else:
        json_data = None


# 需求文档分析
def requirements_doc_analysis():
    content = read_docx()

    prompt = f"""你是一个资深测试工程师。现在会提供给你一份需求文档，请提取出需求文档中的待实现功能点，每一个功能点,需要有唯一标识以及功能描述，并用列表格式输出，只输出结果，不需要思考过程。
    需求文档内容：{content}
    请输出：
    1.  **核心变更点**：用一句话总结。
    2.  **需求功能点**：列出待实现的功能点，每个功能点需要有唯一标识以及功能描述，并使用列表格式输出。
    3.  **风险等级**：高/中/低，并说明理由。"""
    client = OpenAI(
        # 若没有配置环境变量，请用百炼API Key将下行替换为：api_key="sk-xxx",
        api_key='sk-8dcd9ec46bbe42f3947c71d27a21774d',
        base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
    )
    completion = client.chat.completions.create(
        # 模型列表：https://help.aliyun.com/zh/model-studio/getting-started/models
        model="qwen3-coder-flash",
        messages=[
            {"role": "system", "content": "You are a helpful assistant."},
            {"role": "user", "content": f"{prompt}"},
        ],
        # Qwen3模型通过enable_thinking参数控制思考过程（开源版默认True，商业版默认False）
        # 使用Qwen3开源版模型时，若未启用流式输出，请将下行取消注释，否则会报错
        # extra_body={"enable_thinking": False},
    )
    res = completion.model_dump()['choices'][0]['message']['content']
    return res


# git代码差异分析
def get_git_diff(repo_path: str, source_branch: str, target_branch: str) -> str:
    """
    获取两个分支之间的差异对比 (diff)

    Args:
        repo_path: Git仓库本地路径
        source_branch: 源分支（例如：develop）
        target_branch: 目标分支（例如：staging）

    Returns:
        差异对比的字符串内容
    """
    try:
        # 切换至仓库目录
        original_cwd = os.getcwd()
        os.chdir(repo_path)
        # 执行 git diff 命令
        cmd2 = ['git', 'remote', 'add', 'origin', 'https://gitee.com/jiang-hangjie/test_demo1.git']
        subprocess.run(cmd2, capture_output=True, text=True, check=True)
        # 使用 '--diff-filter=d' 忽略已删除文件，专注于新增和修改，可根据需要调整
        cmd1 = ['git', 'fetch']
        result1 = subprocess.run(cmd1, capture_output=True, text=True, check=True)
        cmd = ['git', 'diff', f'{target_branch}..{source_branch}', '--diff-filter=d']
        result = subprocess.run(cmd, capture_output=True, text=True, check=True)

        # 切回原目录
        os.chdir(original_cwd)

        return result.stdout
    except subprocess.CalledProcessError as e:
        print(f"Git命令执行错误: {e}")
        return ""
    except Exception as e:
        print(f"获取差异时发生错误: {e}")
        return ""


def code_diff_analysis(requirements_points: str, code_diff_content: str) -> str:
    json_formate = {
        "related_requirements": [
            {
                "requirement_id": "REQ-001",
                "description": "需求描述",
                "implementation_match": "符合程度描述",
                "score": 4,
                "confidence": "high"
            }
        ],
        "unrelated_changes": [
            {
                "change_description": "变更描述",
                "reason": "无关原因",
                "risk_level": "low/medium/high"
            }
        ],
        "potential_issues": [
            {
                "issue_type": "问题类型",
                "description": "问题描述",
                "severity": "low/medium/high/critical",
                "suggestion": "改进建议"
            }
        ]
    }
    prompt = f"""你是一个资深测试架构师。现在会提供给你一份需求核心功能报告，一份git代码差异对比，请根据需求功能报告和git代码差异对比，分析以下代码变更是否符合需求文档，并识别与需求无关的代码。
    需求文档内容：{requirements_points}
    代码差异对比：{code_diff_content}
    请按以下格式分析：
    1.相关需求匹配：
        列出每个变更对应的需求项
        说明实现是否符合需求描述
        评分（1-5分，5为完全符合）
    2.与需求无关的变更：
        识别不直接支持需求的代码
        说明可能的原因（重构、技术债务、误改等）
    3.潜在问题
        逻辑错误风险
        性能问题
        安全顾虑
    4.改进建议
    
    请用JSON格式返回分析结果,格式如下，不要输出其他内容。:
    {json_formate}
    """
    client = OpenAI(
        # 若没有配置环境变量，请用百炼API Key将下行替换为：api_key="sk-xxx",
        api_key='sk-8dcd9ec46bbe42f3947c71d27a21774d',
        base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
    )
    completion = client.chat.completions.create(
        # 模型列表：https://help.aliyun.com/zh/model-studio/getting-started/models
        model="qwen3-coder-flash",
        messages=[
            {"role": "system", "content": "You are a helpful assistant."},
            {"role": "user", "content": f"{prompt}"},
        ],
        # Qwen3模型通过enable_thinking参数控制思考过程（开源版默认True，商业版默认False）
        # 使用Qwen3开源版模型时，若未启用流式输出，请将下行取消注释，否则会报错
        # extra_body={"enable_thinking": False},
    )
    ai_res = completion.model_dump()['choices'][0]['message']['content']
    return ai_res


class ReportGenerator:
    def generate_analysis_report(self, analysis_results, output_format="markdown"):
        """生成分析报告"""
        if output_format == "markdown":
            return self.generate_markdown_report(analysis_results)
        elif output_format == "json":
            return json.dumps(analysis_results, indent=2, ensure_ascii=False)

    def generate_markdown_report(self, analysis_results):
        """生成Markdown格式报告"""
        report = []
        report.append("# 代码变更分析报告\n")

        # 总体评分
        report.append(f"## 总体符合度评分: {analysis_results['compliance_score']}/100\n")

        # 需求覆盖情况
        report.append("## 需求覆盖分析\n")
        for req in analysis_results["requirement_coverage"]:
            report.append(f"### {req['requirement_id']} - 评分: {req['score']}/5")
            report.append(f"- **实现匹配**: {req['implementation_match']}")
            report.append(f"- **置信度**: {req['confidence']}\n")

        # 无关变更
        if analysis_results["unrelated_changes"]:
            report.append("## ⚠️ 与需求无关的变更\n")
            for change in analysis_results["unrelated_changes"]:
                report.append(f"### {change['change_description']}")
                report.append(f"- **原因**: {change['reason']}")
                report.append(f"- **风险等级**: {change['risk_level']}\n")

        # 潜在问题
        if analysis_results["potential_issues"]:
            report.append("## 🚨 潜在问题\n")
            for issue in analysis_results["potential_issues"]:
                report.append(f"### {issue['issue_type']} - 严重性: {issue['severity']}")
                report.append(f"- **描述**: {issue['description']}")
                report.append(f"- **建议**: {issue['suggestion']}\n")

        return "\n".join(report)


if __name__ == '__main__':
    requirements_points = requirements_doc_analysis()
    print(requirements_points)
    print('------------')
    code_diff_content = get_git_diff(repo_path=r'D:\Programming_soft\ai_guard', source_branch='develop',
                                     target_branch='release/develop')
    res = code_diff_analysis(code_diff_content=code_diff_content, requirements_points=requirements_points)
    print(res)
